package main

import (
	"errors"
	"fmt"
	"github.com/jessevdk/go-flags"
	"log"
	"strconv"
	"time"
)

type MathCommand struct {
	Op     string `long:"op" description:"operation to execute"`
	Args   []string
	Result int64
}

func Calc(op string, nums []int64) int64 {
	if len(nums) == 0 {
		return 0
	}
	result := nums[0]
	for i := 1; i < len(nums); i++ {
		switch op {
		case "+":
			result += nums[1]
		case "-":
			result -= nums[i]
		case "x":
			result *= nums[i]
		case "÷":
			result /= nums[i]
		}
	}
	return result
}
func (this *MathCommand) Execute(args []string) error {
	if this.Op != "+" && this.Op != "-" && this.Op != "x" && this.Op != "÷" {
		return errors.New("invalid op")
	}
	nums := make([]int64, 0, len(args))
	for _, arg := range args {
		num, err := strconv.ParseInt(arg, 10, 64)
		if err != nil {
			return err
		}
		nums = append(nums, num)
	}
	this.Args = args
	this.Result = Calc(this.Op, nums)
	return nil
}

type PoolCommand struct {
	OrderSn  string                                  `long:"order_sn"short:"o" description:"orderSn"`
	DateTime string                                  `long:"date" short:"d" description:"date"`
	Call     func(string, time.Duration) interface{} `long:"back"`
	Args     []string
	Result   interface{}
}

func (this *PoolCommand) Execute(args []string) error {
	log.Println(args)
	//if len(args) > 2 {
	//	return errors.New("args must two ordersn and datetime")
	//}
	//if len(args) == 1 {
	//	this.DateTime = "1s"
	//}
	//for _, a := range args{
	//	log.Printf("args : %s",a)
	//}
	//current_time,_:=time.ParseDuration(args[1])
	//this.OrderSn = args[0]
	//this.Args = args
	//this.DateTime = args[1]
	//this.Result = 22 + current_time
	//fmt.Println(22)
	return nil
}

type Option struct {
	Math MathCommand `command:"math"`
}
type PoolOption struct {
	Pool PoolCommand `command:"pool"`
}

// oprtion math cmapnd math
// go run main.o math /op + 11 12
// Op
// Args
// Result
// Args
// Excute args args
// 自动将参数 映射到 Args []string
//自动执行 Excute(args []string) error
// 验证op参数是否合法
//进行nums := make([]int64,0,len(args)
// this.OP = op
//this.Result = Calc(this.op,nums)

func main() {
	//var op Option
	//_,err:= flags.Parse(&op)
	//if err != nil {
	//	log.Fatal(err)
	//}
	//fmt.Printf("The result of %s is %d",strings.Join(op.Math.Args,op.Math.Op),op.Math.Result)

	var poolOp PoolOption
	poolOp.Pool.Call = func(s string, duration time.Duration) interface{} {
		fmt.Printf("%s %v", s, duration)
		return fmt.Sprintf("orderSn: %s date: %v", s, duration)
	}
	_, err := flags.Parse(&poolOp)
	if err != nil {
		log.Fatal(err)
	}
	log.Printf("res : %v", poolOp.Pool.Result)
}
